<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模拟敲鼓效果</title>
    <style>
        .content {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 10px;
        }

        .list {
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            width: 120px;
            height: 120px;
            border: 1px solid #D8D8D8;
            text-align: center;
            transition: all .07s ease;
            /*text-shadow: 0 0 .5rem black;*/
        }

        .code {
            font-size: 20px;
            font-weight: bold;
            margin-bottom: 20px;
        }

        .playing {
            transform: scale(1.1);
            border-color: #ffc600;
            box-shadow: 0 0 1rem #ffc600;
        }
    </style>
</head>
<body>
<div id="root"></div>
</body>
<script src="../lib/babel.min.js"></script>
<script async src="../lib/es-module-shims.js"></script>
<script type="importmap">
        {
          "imports": {
            "react": "https://esm.sh/react?dev",
            "react-dom/client": "https://esm.sh/react-dom/client?dev"
          }
        }
</script>

<script type="text/babel" data-type="module">
    import React, {StrictMode, useState, useEffect, useRef} from 'react';
    import {createRoot} from 'react-dom/client';


    function useKeySoundController() {
        const audioRefs = useRef({});
        const elementRefs = useRef({});
        useEffect(() => {
            const removeTransition = (e) => {
                if (e.propertyName !== 'transform') return;
                e.target.classList.remove('playing');
            }
            const handleKeyDown = (e) => {
                if (e.repeat) return;
                const key = e.keyCode?.toString();
                console.log(key);
                const audio = audioRefs.current[key];
                const element = elementRefs.current[key];

                if (!audio) return;

                if (element) {
                    element.classList.add('playing');
                    element.removeEventListener('transitionend', removeTransition);
                    element.addEventListener('transitionend', removeTransition)
                    // setTimeout(() => element.classList.remove('playing'), 100);
                }
                audio.currentTime = 0;
                audio.play().catch(error => {
                    console.error('播放失败:', error);
                });
            };
            console.log('绑定事件监听器');  // 观察控制台输出次数
            window.removeEventListener('keydown', handleKeyDown)
            window.addEventListener('keydown', handleKeyDown);
            return () => {
                console.log('移除事件监听器');
                window.removeEventListener('keydown', handleKeyDown)
            };
        }, []);

        return {audioRefs, elementRefs};
    }

    let list = [
        {
            code: 'A',
            key: '65',
            sound: 'clap'
        },
        {
            code: 'S',
            key: '83',
            sound: 'hihat'
        }, {
            code: 'D',
            key: '68',
            sound: 'kick'
        }, {
            code: 'F',
            key: '70',
            sound: 'openhat'
        }, {
            code: 'G',
            key: '71',
            sound: 'boom'
        }, {
            code: 'H',
            key: '72',
            sound: 'ride'
        },
        {
            code: 'J',
            key: '74',
            sound: 'snare'
        },
        {
            code: 'K',
            key: '75',
            sound: 'tom'
        }, {
            code: 'L',
            key: '76',
            sound: 'tink'
        }

    ]

    function App() {

        let keydownRef = useRef(null)

        const {audioRefs, elementRefs} = useKeySoundController();

        let spanDom = list.map(item =>
            <div className="list" ref={ref => elementRefs.current[item.key] = ref} data-key={item.key} key={item.key}>
                <kbd className="code">{item.code}</kbd>
                <div>{item.sound}</div>
                <audio ref={ref => {
                    if (ref) {
                        audioRefs.current[item.key] = ref
                    } else {
                        // 改进 audio ref 的内存管理（元素卸载时自动删除引用）
                        delete audioRefs.current[item.key]
                    }
                }
                }
                       data-key={item.key} src={`sounds/${item.sound}.wav`}></audio>
            </div>
        );

        return (
            <div className="content">
                {spanDom}
            </div>
        );
    }

    const container = document.getElementById('root');
    const root = createRoot(container);

    root.render(
        <StrictMode>
            <App/>
        </StrictMode>
    );
</script>
</html>
